#include "../include/MainFrame.h"
#include "../include/AccountManager.h"

CAccountManager::CAccountManager(CMainFrame* pParent, wxWindowID ID, CMySqlWrapper* pMySql)
: wxNotebook(pParent, ID),
  m_pParent(pParent), m_pMySql(pMySql)
{

}

CAccountManager::~CAccountManager()
{

}

int CAccountManager::LoadAccounts()
{
    wxString Query = wxString::Format("SELECT * FROM %s.tab_AccountList", m_pMySql->GetDefaultDatabase() );
    if (!m_pMySql->RunQuery(Query) )
    {
        mmErrorDlg(this, m_pMySql->GetLastError() );
        return -1;
    }

    SAccountInfo AccountInfo;
    while(this->GetNextAccountFromResultSet(AccountInfo) )
    {
        // Add the account page to the wxNotebook display
        this->AddAccount(AccountInfo, m_pParent->GetAccountPlugin(AccountInfo.AccountType) );
    }

    return (int)this->GetPageCount();
}

bool CAccountManager::GetNextAccountFromResultSet(SAccountInfo& Account)
{
    MYSQL_ROW Row = m_pMySql->GetNextRowFromResultSet();
    if (Row)
    {
        Account.ID                   = (size_t)Row[0];
        Account.AccountName          = (wxString)Row[1];
        Account.AccountNumber        = (wxString)Row[2];
        Account.AccountType          = (wxString)Row[3];
        Account.BankName             = (wxString)Row[4];
        Account.BankAddress          = (wxString)Row[5];
        Account.BankPhone            = (wxString)Row[6];
        Account.CurrentBalance       = (double)Row[7] ;
        Account.DateOpened           = (wxString)Row[8];
        Account.OpeningBalance       = (double)Row[9] ;
        Account.LastStatementDate    = (wxString)Row[10];
        Account.LastStatementBalance = (double)Row[11] ;
        Account.AccountFileName      = (wxString)Row[12];
        return true;
    }
    return false;
}

bool CAccountManager::AddAccount(SAccountInfo& AccountInfo, CAccountPlugin* pPlugin, const bool IsNewAccount)
{
    // create the account
    CAccount* pAccount = new CAccount(this, wxID_ANY, AccountInfo, pPlugin, m_pMySql);

    if (IsNewAccount)
    {
        pAccount->SaveAccountData(IsNewAccount);
        pAccount->CreateTransactionTable();
    }
    else
    {
        pAccount->LoadTransactionTable();
    }

    // create a new page for the account
    wxString Text = wxString::Format("%s (%1.2f)", AccountInfo.AccountName, AccountInfo.CurrentBalance);
    this->AddPage(pAccount, Text, true);
    m_AccountIDs.insert(std::make_pair(AccountInfo.ID, this->GetSelection() ) );

    // set the balance display on the account page
    pAccount->SetTotalBalance(AccountInfo.CurrentBalance);

    return true;
}

bool CAccountManager::CreateFirstAccount(const SUserInfo& User)
{
    wxString msg = wxString::Format(_("OK, %s, now let's create your first account!\n"), User.FirstName);
    mmMessageDlg(this, msg);
    SAccountInfo AccountInfo = { 0, "", "", "", "", "", "", 0.00, "", 0.00, "", 0.00, "" };
    return this->EditAccount(AccountInfo, true, true);
}

/* FIXME (Developer 1#2#): Account type list box in .xrc file is not displaying right.  The edit box
is not tall enough to fit the text*/
bool CAccountManager::EditAccount(SAccountInfo& AccountInfo, const bool CanEdit, const bool IsNewAccount)
{
    wxArrayString AccountTypes;
    if (!m_pParent->GetAvailableAccountTypes(AccountTypes) )
    {
        mmErrorDlg(this, _("No Available Account Types") );
        return false;
    }
    CEditAccountDlg Dlg(this, AccountInfo, AccountTypes, CanEdit, IsNewAccount);
    if (Dlg.ShowModal() == wxID_OK)
    {
        // if it is a new account
        if (IsNewAccount)
        {
            // set the file name for the account transaction list
            this->CreateAccountFileName(AccountInfo, true);

            // Add the account page to AccountManager
            this->AddAccount(AccountInfo, m_pParent->GetAccountPlugin(AccountInfo.AccountType), IsNewAccount);
        }
        else
        {
            // Update the account page in AccountManager
            this->UpdateAccount(AccountInfo);
        }
    }
    return true;
}

void CAccountManager::CreateAccountFileName(SAccountInfo& AccountInfo, const bool ReplaceCurrentFileName)
{
    if (!AccountInfo.AccountFileName.IsEmpty() && ReplaceCurrentFileName)
        return;

    // get the length of the account name
    const size_t length = AccountInfo.AccountName.Length();

    // remove any spaces from the account name
    wxString str;
    for (size_t x = 0; x < length; x++)
    {
        if (AccountInfo.AccountName[x] != ' ')
        {
            str += AccountInfo.AccountName[x];
        }
    }
    AccountInfo.AccountFileName = str.Lower();
    return;
}

CAccount* CAccountManager::GetAccount(size_t AccountID)
{
    ACCOUNT_ID_MAP_ITER iter = m_AccountIDs.find(AccountID);
    if (iter != m_AccountIDs.end() )
        return (CAccount*)this->GetPage(iter->second);
    return NULL;
}

bool CAccountManager::UpdateAccount(SAccountInfo& AccountInfo)
{
    // get the account to update
    CAccount* pAccount = this->GetAccount(AccountInfo.ID);
    if (pAccount == NULL)
        return false;

    // update and save the account data
    pAccount->UpdateAccountData(AccountInfo);
    pAccount->SaveAccountData(false);

    // update the account page tab text
    this->SetAccountTabText(AccountInfo);

    // set the balance display on the account page
    pAccount->SetTotalBalance(AccountInfo.CurrentBalance);

    return true;
}

void CAccountManager::SetAccountTabText(const SAccountInfo& AccountInfo)
{
    ACCOUNT_ID_MAP_ITER iter = m_AccountIDs.find(AccountInfo.ID);
    if (iter != m_AccountIDs.end() )
    {
        wxString Text = wxString::Format("%s (%1.2f)", AccountInfo.AccountName, AccountInfo.CurrentBalance);
        this->SetPageText(iter->second, Text);
    }
    return;
}


